home *** CD-ROM | disk | FTP | other *** search
- /*
- ***********************************************************************
- *
- *
- * Event Handler Classes
- * Implementation
- *
- *
- ***********************************************************************
- */
-
- #include "EventHandlers.h"
- #include "window.h"
- #include <SIOUX.h>
-
- #if 0
- // Pointer to a null event handler on the top
- // of the chain of registered handlers.
- // For now we don't have a chain, actually
- // so this points to the only one event handler,
- // or nil
- NullEventHandler * NullEventHandler::first_handler = nil;
- #endif
-
- bool EventHandler::putback_pending = false;
- EventRecord EventHandler::putback_event;
-
- // Un-get an event. The 'event' becomes the first event
- // returned by EventHandler::wait_next_event() or in the
- // EventHandler::loop()
- void EventHandler::put_back(const EventRecord& event)
- {
- assert( !putback_pending );
- putback_event = event;
- putback_pending = true;
- }
-
- // A shorthand of put_back() if I want to create a
- // 'myevent' and push it back into the "event queue"
- void EventHandler::put_back_my_event
- (const EventModifiers modifiers, const UInt32 message, const Point where)
- {
- assert( !putback_pending );
- putback_event.what = mykind;
- putback_event.message = message;
- putback_event.when = 0;
- putback_event.where = where;
- putback_event.modifiers = modifiers;
- putback_pending = true;
- }
-
- void EventHandler::put_back_my_event(const EventModifiers modifiers, const UInt32 message)
- {
- assert( !putback_pending );
- putback_event.what = mykind;
- putback_event.message = message;
- putback_event.when = 0;
- // putback_event.where = where;
- putback_event.modifiers = modifiers;
- putback_pending = true;
- }
-
-
- // A wrap around WaitNextEvent() to take care
- // of put-back events, and to transparently
- // process high-level events
- bool EventHandler::wait_next_event(EventRecord& event, const int timeout)
- {
- if( putback_pending )
- putback_pending = false, event = putback_event;
- else
- if( !WaitNextEvent(everyEvent, &event, timeout, nil) )
- return false; // That was a null-event
-
- if( event.what == kHighLevelEvent )
- {
- OSErr error = AEProcessAppleEvent(&event);
- if( error != errAEEventNotHandled )
- do_well(error);
- return wait_next_event(event,timeout); // Done with this event, wait for another
- }
-
- // If there is a SIOUX console window around,
- // check to see if it claims the event
- // We must give SIOUX a chance to handle its
- // update/activate events (which would be
- // generated for the SIOUX window when we open
- // our window or change the color environment)
- // Otherwise, our update-event based animation
- // won't work
- extern WindowPtr SIOUXTextWindow;
- if( ((WindowPtr)event.message == SIOUXTextWindow) && SIOUXHandleOneEvent(&event) )
- return wait_next_event(event,timeout); // Done with this event, wait for another
- return true;
- }
-
-
-
- // Event handling loop. Returns only when the
- // WindowObject is to be destroyed
- // Performs a very basic dispatching of a received event
- void EventHandler::loop(void)
- {
- for(;;)
- {
- if( !wait_next_event(the_event,event_timeout) )
- if( serviced_window.handle_null_event(the_event.when) )
- continue;
- else
- return; // Null event handler decided it's time to quit
-
- if( !serviced_window.handle_event(the_event) )
- return; // The handler decided it doesn't want any more events
- }
- }
-
- // Flush incidental events: mainly, take care of
- // update/activate/etc events that might be pending on
- // a SIOUX console if any
- // Pending update events on windows other than our main
- // map window interferes with the way we do animation
- // (based on a set of update events)
- // Note that update/activate events are not actually
- // placed in a OS even queue, but genereated by the
- // toolbox for the window which happens to be on the front
- void EventHandler::flush_side_events(void)
- {
- EventRecord the_event;
- while( wait_next_event(the_event,0) && SIOUXHandleOneEvent(&the_event) )
- ;
- if( the_event.what != nullEvent )
- put_back(the_event);
- }
-